﻿namespace FATEFAKE
{
    #region using directives
    using System.Collections.Generic;
    using System.IO;
    using System.Text.RegularExpressions;
    #endregion

    class FateCommands
    {
        private IList<FateCommand> fateCommandList;

        public static FateCommands CreateFromFile(string fileName)
        {
            using (TextReader tr = File.OpenText(fileName))
            {
                return CreateFromTextReader(tr);
            }
        }

        public IList<FateCommand> FateCommandList
        {
            get { return this.fateCommandList; }
        }

        private FateCommands()
        {
            this.fateCommandList = new List<FateCommand>();
        }

        private void AddCommand(FateCommand command)
        {
            this.fateCommandList.Add(command);
        }

        private static FateCommands CreateFromTextReader(TextReader textReader)
        {
            FateCommands cmds = new FateCommands();
            for (; ; )
            {
                string line = textReader.ReadLine();
                if (line == null)
                {
                    break;
                }

                FateCommand cmd = ParseLine(line);
                if (cmd != null)
                {
                    cmds.AddCommand(cmd);
                }
            }

            return cmds;
        }

        private static FateCommand ParseLine(string line)
        {
            if (line.StartsWith("#"))
            {
                return null;
            }

            if (!Regex.IsMatch(line, @"^.*fate-run\.sh.*"))
            {
                return null;
            }

            Match m = Regex.Match(line, "^*fate-run\\.sh\\s+" +
                                        "(?<TESTNAME>[a-zA-Z0-9-._]+?)\\s+" +
                                        "[\\u0022'](?<SAMPLES>.*?)[\\u0022']\\s+" +
                                        "[\\u0022'](?<TARGETEXEC>.*?)[\\u0022']\\s+" +
                                        "[\\u0022'](?<TARGETPATH>.*?)[\\u0022']\\s+" +
                                        "['](?<COMMAND>.*?)[']\\s+" +
                                        "[\\u0022'](?<CMP>.*?)[\\u0022']\\s+" +
                                        "[\\u0022'](?<REF>.*?)[\\u0022']\\s+" +
                                        "[\\u0022'](?<FUZZ>.*?)[\\u0022']\\s+" +
                                        "[\\u0022'](?<THREADS>.*?)[\\u0022']\\s+" +
                                        "[\\u0022'](?<THREADTYPE>.*?)[\\u0022']\\s+" +
                                        "[\\u0022'](?<CPUFLAGS>.*?)[\\u0022']\\s+" +
                                        "[\\u0022'](?<CMPSHIFT>.*?)[\\u0022']\\s+" +
                                        "[\\u0022'](?<CMPTARGET>.*?)[\\u0022']\\s+" +
                                        "[\\u0022'](?<SIZETOLERANCE>.*?)[\\u0022']\\s+" +
                                        "[\\u0022'](?<CMPUNIT>.*?)[\\u0022']");

            var testname = m.Groups["TESTNAME"];
            var command = m.Groups["COMMAND"];

            if (testname.Success && command.Success)
            {
                var cmp = m.Groups["CMP"];
                var reference = m.Groups["REF"];
                var cmpUnit = m.Groups["CMPUNIT"];
                var cmpShift = m.Groups["CMPSHIFT"];
                var fuzz = m.Groups["FUZZ"];
                var sizeTolerance = m.Groups["SIZETOLERANCE"];
                var cmpTarget = m.Groups["CMPTARGET"];
                return new FateCommand(
                                testname.Value,
                                command.Value,
                                cmp.Success ? cmp.Value : null,
                                reference.Success ? reference.Value : null,
                                cmpUnit.Success ? cmpUnit.Value : null,
                                cmpShift.Success ? cmpShift.Value : null,
                                fuzz.Success ? fuzz.Value : null,
                                sizeTolerance.Success ? sizeTolerance.Value : null,
                                cmpTarget.Success ? cmpTarget.Value : null);
            }

            return null;
        }

    }
}
